﻿using Airthmetic;
using BaseTool;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

namespace StructuredLightSystemUI
{
    /// <summary>
    /// 辅助功能页面
    /// </summary>
    public partial class ConAuxiliaryFunction : UserControl
    {
        /// <summary> 棋盘格工具 </summary>
        private CheckerboardImageTool cTool
        {
            set { MyGlobal.CheckerboardImageTool = value; }
            get { return MyGlobal.CheckerboardImageTool; }
        }
        /// <summary> 条纹光栅图像工具 </summary>
        private StripedGratingImageTool stTool
        {
            set { MyGlobal.StripedGratingImageTool = value; }
            get { return MyGlobal.StripedGratingImageTool; }
        }

        /// <summary> 正在刷新控件 </summary>
        private bool isRefreshControl_CheckerboardImage = false;
        /// <summary> 正在刷新控件 </summary>
        private bool isRefreshControl_StripedGratingImage = false;

        #region 构造、初始化
        /// <summary>
        /// 构造
        /// </summary>
        public ConAuxiliaryFunction()
        {
            InitializeComponent();
            //读取参数事件
            Machine.ChangeProductAction += OpenControl;
        }

        //加载时
        private void ConAuxiliaryFunction_Load(object sender, EventArgs e)
        {

        }

        /// <summary> 打开用户控件 </summary>
        public void OpenControl()
        {
            //棋盘格工具 刷新控件参数
            RefreshCheckerboardImageControl();

            //条纹光栅图像工具 刷新控件参数
            RefreshStripedGratingImageControl();
        }

        /// <summary> 关闭用户控件 </summary>
        public void CloseControl()
        {

        }
        #endregion

        #region 侧边栏事件
        //棋盘格工具
        private void b_CT_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 0;
        }
        //条纹光栅图像工具
        private void b_ST_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 1;
        }
   
        //隐藏侧边栏
        private void b_Collapsed_Click(object sender, EventArgs e)
        {
            ChangeCollapsed(true);
        }
        //切换侧边栏显示/隐藏
        private void 侧边栏隐藏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeCollapsed();
        }

        /// <summary>
        /// 切换侧边栏显示/隐藏
        /// </summary>
        private void ChangeCollapsed()
        {
            ChangeCollapsed(!splitContainer1.Panel1Collapsed);
        }
        /// <summary>
        /// 设置侧边栏显示/隐藏
        /// </summary>
        private void ChangeCollapsed(bool Collapsed)
        {
            splitContainer1.Panel1Collapsed = Collapsed;
            侧边栏隐藏ToolStripMenuItem.Text = Collapsed ? $"侧边栏显示" : "侧边栏隐藏";
        }

        #endregion

        #region 棋盘格工具
        /// <summary>
        /// 刷新棋盘格工具
        /// </summary>
        private void RefreshCheckerboardImageControl()
        {
            //挂起标志位
            isRefreshControl_CheckerboardImage = true;

            try
            {
                //一格像素长度
                nud_CTPixelWidth.Value = cTool.OneGridPixelWidth;
                //一格实际长度
                nud_CTActualLength.Value = (int)cTool.OneGridActualLength;
                //单元格数量，宽
                nud_CTBoardWidth.Value = cTool.BoardSizeWidth;
                //单元格数量，高
                nud_CTBoardHeight.Value = cTool.BoardSizeHeight;


            }
            catch (Exception ex)
            {
                Log.SaveError(ex);
            }
            finally
            {
                //标志位清空
                isRefreshControl_CheckerboardImage = false;
                //实时刷新显示
                RefreshPictureBox();
            }
        }
        //一格像素长度
        private void nud_CTPixelWidth_ValueChanged(object sender, EventArgs e)
        {
            if (isRefreshControl_CheckerboardImage)
                return;
            cTool.OneGridPixelWidth = (int)nud_CTPixelWidth.Value;
            SaveParam();
            RefreshPictureBox(false);
        }
        //一格实际长度
        private void nud_CTActualLength_ValueChanged(object sender, EventArgs e)
        {
            if (isRefreshControl_CheckerboardImage)
                return;
            cTool.OneGridActualLength = (double)nud_CTActualLength.Value;
            SaveParam();
            RefreshPictureBox(false);
        }
        //单元格数量
        private void nud_CTBoard_ValueChanged(object sender, EventArgs e)
        {
            if (isRefreshControl_CheckerboardImage)
                return;
            cTool.BoardSizeWidth = (int)nud_CTBoardWidth.Value;
            cTool.BoardSizeHeight = (int)nud_CTBoardHeight.Value;
            SaveParam();
            RefreshPictureBox();
        }

        /// <summary>
        /// 实时刷新显示
        /// </summary>
        /// <param name="changeImage"> 刷新图像 </param>
        private void RefreshPictureBox(bool changeImage = true)
        {
            try
            {
                l_CTImagePixel.Text = $"棋盘格分辨率：{cTool.ImagePixelWidth} * {cTool.ImagePixelHeight}";
                l_CTActualWidth.Text = $"棋盘格实际长度：{cTool.ImageActualWidth} x {cTool.ImageActualHeight} mm";
                l_CTPPI.Text = $"PPI：{cTool.PPI}";
                if (changeImage /*&& this.Parent != null*/)
                    cpb_CT.ShowImage = cTool.GetImage();
            }
            catch (Exception ex)
            {
                Log.SaveError(ex);
            }
        }
        //生成并保存图片
        private void b_CTSaveImage_Click(object sender, EventArgs e)
        {
            cTool.Generate();
        }
        //打开保存图片文件夹
        private void b_OpenSaveFolder_Click(object sender, EventArgs e)
        {
            FileTool.OpenFolder(PathTool.DataCheckerBoardImagePath, true);
        }
        //重置参数
        private void b_CTReset_Click(object sender, EventArgs e)
        {
            cTool = new CheckerboardImageTool();
            SaveParam();
            RefreshCheckerboardImageControl();
        }
        #endregion

        #region 条纹光栅图像工具
        /// <summary>
        /// 条纹光栅图像工具
        /// </summary>
        private void RefreshStripedGratingImageControl()
        {
            //挂起标志位
            isRefreshControl_StripedGratingImage = true;

            try
            {
                //图片尺寸
                nud_STWidth.Value = stTool.GrayCode.ImageWidth;
                nud_STHeight.Value = stTool.GrayCode.ImageHeight;
                stTool.PhaseShift.ImageWidth = stTool.GrayCode.ImageWidth;
                stTool.PhaseShift.ImageHeight = stTool.GrayCode.ImageHeight;

                //格雷码
                cb_STAllBlackAndWhite.Checked = stTool.GrayCode.IsAllWhiteAndBlack;
                cb_STAutoDepth.Checked = stTool.GrayCode.IsAutoDepth;
                cb_STComplementaryGrayCode.Checked = stTool.GrayCode.IsComplementaryGrayCode;
                if (stTool.GrayCode.IsAutoDepth)
                {
                    stTool.GrayCode.VerticalDepth = stTool.GrayCode.BesttVerticalDepth;
                    stTool.GrayCode.HorizontalDepth = stTool.GrayCode.BesttHorizontalDepth;
                }
                nud_STVerticalDepth.Enabled = !stTool.GrayCode.IsAutoDepth;
                nud_STHorizontalDepth.Enabled = !stTool.GrayCode.IsAutoDepth;
                nud_STVerticalDepth.Value = stTool.GrayCode.VerticalDepth;
                nud_STHorizontalDepth.Value = stTool.GrayCode.HorizontalDepth;

                //相移法
                nud_STA.Value = stTool.PhaseShift.A;
                nud_STB.Value = stTool.PhaseShift.B;
                nud_STN.Value = stTool.PhaseShift.N;
                nud_STT.Value = (int)stTool.PhaseShift.T;
                cb_STIsVertical.Checked = stTool.PhaseShift.IsVertical;
                cb_STIsVertical.Text = stTool.PhaseShift.IsVertical ? "垂直" : "水平";
            }
            catch (Exception ex)
            {
                Log.SaveError(ex);
            }
            finally
            {
                //标志位清空
                isRefreshControl_StripedGratingImage = false;
            }
        }
        //条纹光栅参数变动
        private void nud_cb_PhaseShift_ValueChanged(object sender, EventArgs e)
        {
            if (isRefreshControl_StripedGratingImage)
                return;

            //图片尺寸
            stTool.GrayCode.ImageWidth = (int)nud_STWidth.Value;
            stTool.GrayCode.ImageHeight = (int)nud_STHeight.Value;
            stTool.PhaseShift.ImageWidth = stTool.GrayCode.ImageWidth;
            stTool.PhaseShift.ImageHeight = stTool.GrayCode.ImageHeight;

            //格雷码
            stTool.GrayCode.IsAutoDepth = cb_STAutoDepth.Checked;
            stTool.GrayCode.IsAllWhiteAndBlack = cb_STAllBlackAndWhite.Checked;
            stTool.GrayCode.IsComplementaryGrayCode = cb_STComplementaryGrayCode.Checked;
            nud_STVerticalDepth.Enabled = !stTool.GrayCode.IsAutoDepth;
            nud_STHorizontalDepth.Enabled = !stTool.GrayCode.IsAutoDepth;
            if (stTool.GrayCode.IsAutoDepth)
            {
                stTool.GrayCode.VerticalDepth = stTool.GrayCode.BesttVerticalDepth;
                stTool.GrayCode.HorizontalDepth = stTool.GrayCode.BesttHorizontalDepth;
                isRefreshControl_StripedGratingImage = true;
                nud_STVerticalDepth.Value = stTool.GrayCode.VerticalDepth;
                nud_STHorizontalDepth.Value = stTool.GrayCode.HorizontalDepth;
                isRefreshControl_StripedGratingImage = false;
            }
            stTool.GrayCode.VerticalDepth = (int)nud_STVerticalDepth.Value;
            stTool.GrayCode.HorizontalDepth = (int)nud_STHorizontalDepth.Value;

            //相移法
            stTool.PhaseShift.IsVertical = cb_STIsVertical.Checked;
            cb_STIsVertical.Text = stTool.PhaseShift.IsVertical ? "垂直" : "水平";
            stTool.PhaseShift.A = (int)nud_STA.Value;
            stTool.PhaseShift.B = (int)nud_STB.Value;
            stTool.PhaseShift.N = (int)nud_STN.Value;
            stTool.PhaseShift.T = (double)nud_STT.Value;

            //保存
            SaveParam();
        }

        //生成格雷码
        private void b_GenGrayCode_Click(object sender, EventArgs e)
        {
            try
            {
                int count1 = stTool.PatternList.Count;
                Stopwatch sw = Stopwatch.StartNew();

                GrayCodeParam grayCodeParam = new GrayCodeParam();
                grayCodeParam.ImageWidth = (int)nud_STWidth.Value;
                grayCodeParam.ImageHeight = (int)nud_STHeight.Value;
                grayCodeParam.IsAllWhiteAndBlack = cb_STAllBlackAndWhite.Checked;
                grayCodeParam.IsComplementaryGrayCode = cb_STComplementaryGrayCode.Checked;
                grayCodeParam.VerticalDepth = (int)nud_STVerticalDepth.Value;
                grayCodeParam.HorizontalDepth = (int)nud_STHorizontalDepth.Value;
                stTool.GenerateGrayCodeImages(grayCodeParam);

                int count2 = stTool.PatternList.Count;
                Log.SaveLog($"生成格雷码成功，耗时{sw.ElapsedMilliseconds}ms，共生成{count2 - count1}/{count2}张图片", LogType.Run, Color.Black);
            }
            catch (Exception ex)
            {
                Log.SaveError(ex, $"生成格雷码异常，{ex.Message}", LogType.Run);
            }
            finally
            {
                ImageListForm.RefreshImageAction?.Invoke();
            }
        }
        //生成相移法
        private void b_GenPhaseShift_Click(object sender, EventArgs e)
        {
            try
            {
                int count1 = stTool.PatternList.Count;
                Stopwatch sw = Stopwatch.StartNew();

                PhaseShiftParam phaseShiftParam = new PhaseShiftParam();
                phaseShiftParam.ImageWidth = (int)nud_STWidth.Value;
                phaseShiftParam.ImageHeight = (int)nud_STHeight.Value;
                phaseShiftParam.A = (int)nud_STA.Value;
                phaseShiftParam.B = (int)nud_STB.Value;
                phaseShiftParam.N = (int)nud_STN.Value;
                phaseShiftParam.T = (int)nud_STT.Value;
                phaseShiftParam.IsVertical = cb_STIsVertical.Checked;
                stTool.GeneratePhaseShiftPatterns(phaseShiftParam);

                int count2 = stTool.PatternList.Count;
                Log.SaveLog($"生成相移光栅成功，耗时{sw.ElapsedMilliseconds}ms，共生成{count2 - count1}/{count2}张图片", LogType.Run, Color.Black);
            }
            catch (Exception ex)
            {
                Log.SaveError(ex, $"生成相移光栅异常，{ex.Message}", LogType.Run);
            }
            finally
            {
                ImageListForm.RefreshImageAction?.Invoke();
            }
        }
        //打开文件夹
        private void b_STOpenFloder_Click(object sender, EventArgs e)
        {
            FileTool.OpenFolder(PathTool.DataPatternImagePath, true);
        }
        //清空图像列表
        private void b_STClear_Click(object sender, EventArgs e)
        {
            stTool.PatternList.Clear();
            ImageListForm.RefreshImageAction?.Invoke();
        }
        //重置参数
        private void b_STReset_Click(object sender, EventArgs e)
        {
            stTool.GrayCode = new GrayCodeParam();
            stTool.PhaseShift = new PhaseShiftParam();
            SaveParam();
            RefreshStripedGratingImageControl();
        }
        //图像列表窗口
        private void b_STImageList_Click(object sender, EventArgs e)
        {
            ImageListForm imageListForm = new ImageListForm(stTool.PatternList);
            imageListForm.Show();
        }
        //保存
        private void b_STSave_Click(object sender, EventArgs e)
        {
            try
            {
                Stopwatch sw = Stopwatch.StartNew();
                string savePath;
                stTool.SavePattern(cb_STSaveOneRowOneCol.Checked, out savePath);

                Log.SaveLog($"保存光栅序列成功，耗时{sw.ElapsedMilliseconds}ms，共保存{stTool.PatternList.Count}张图片，保存路径：{savePath}", LogType.Run, Color.Black);
            }
            catch (Exception ex)
            {
                Log.SaveError(ex, $"保存光栅序列异常，{ex.Message}", LogType.Run);
            }
        }
        //单行/单列
        private void cb_STSaveOneRowOneCol_CheckedChanged(object sender, EventArgs e)
        {
            cb_STSaveOneRowOneCol.Text = cb_STSaveOneRowOneCol.Checked ? "单行/单列" : "全图";
        }

        #endregion

        #region 参数读取保存
        /// <summary>
        /// 保存参数
        /// </summary>
        private void SaveParam()
        {
            //保存棋盘格工具参数
            cTool.Save();

            //保存条纹光栅图像工具参数
            stTool.Save();
        }
        #endregion
    }
}
